import { createApp } from 'vue';
import { domTree } from '../../../../../../../../../global/element/domTree';
import {
  appearElFunc,
  disappearElFunc,
  normalizeContainer,
  packNode,
} from '../../../../../../../../../global/element/Func';
import { ObjectOnlyPushSet } from '../../../../../../../../../global/Func/uniFunc/Func';
import { css_disnone } from '../../../../../../../../DataDefine/sourceData';
import { element_add } from '../../../../../../../../Func/element_add';
import { add_class } from '../../../../../../../../../global/element/class_operate/Func';
import { uni_form_uni_comp_default_cla } from '../../../../../DataDefine/sourceData';
import { element_remove } from '../../../../../../../../Func/element_remove';
import { add_unf_id } from '../../../DataDefine/sourceData';
import { get_cur_active_comps } from '../../get_cur_active_comps';
import { get_uni_form_uni_comp_id } from '../../get_uni_form_uni_comp_id';
import { all_lcs_node } from '../../../../../../../../../global/Func/uniFunc/Func/longest_sequence/Func/longest_common_subsequence/Classes/cla_all_lcs_node';

const remove_add_anima_factory_dataManaTag =
  'remove_add_anima_factory_dataMana';

const all_temp_container_id = 'all_temp_container';

const temo_container_id_prefix = 'temp_container_';

// let all_uni_comp_module = import.meta.glob('../../../../**/*.vue');

class remove_add_anima_factory_dataMana {
  get [Symbol.toStringTag]() {
    return remove_add_anima_factory_dataManaTag;
  }

  constructor(targetEl, virtual_arr) {
    this.targetEl = targetEl;

    this.dom_arr_virtual = virtual_arr;

    // 获取 当前 dom 顺序
    this.dom_arr_truth = get_cur_active_comps();

    // 计算 移除的 元素
    this.#calculate_dom_arr_remove();

    // 计算 当前 剩余元素
    this.#calculate_dom_arr_less();

    // 创建 动态引入 元素 容器元素
    this.#create_all_temp_container_to_dom();

    // 清空 全包含组件元素
    this.#all_temp_container_node.innerHTML = '';

    // 创建 动态引入 元素 子容器元素
    this.#create_temp_container_by_less();
  }

  /**
   * 元素 主体
   * @type {HTMLElement}
   */
  targetEl;

  /**
   * 当前 真实 doc 元素 位置 顺序
   * @type {[]}
   */
  dom_arr_truth;

  /**
   * 目标 doc 元素 位置 顺序
   * @type {[]}
   */
  dom_arr_virtual;

  /**
   * 需要 删除 的 真实 dom 项
   * @type {[]}
   */
  dom_arr_remove = [];

  /**
   * 需要 加载 dom 项
   * @type {[]}
   */
  dom_arr_less = [];

  /**
   * 当前 加载 完毕 的 dom 项
   * @type {[]}
   */
  dom_arr_load = [];

  /**
   * 全包含组件元素
   * @type {HTMLElement}
   */
  #all_temp_container_node;

  /**
   * 开始 组装 引入元素
   */
  #start_packnode = false;

  /**
   * 应用 移入 移除动画
   */
  async active_add_remove_anima() {
    // 引入 元素
    this.#import_less_comps();

    // 移除 元素
    await this.#remove_all_dom_arr_remove();

    // 因为 移除 dom 操作后 当前真实 dom 顺序  会 发生变化 因此 再 实时更新 一下 dom 顺序
    this.dom_arr_truth = get_cur_active_comps();

    console.log('怎么 好像 没 整理？');
    // 整理 当前 元素 顺序
    await this.#sort_cur_truth_dom();

    this.#start_pack_less_comps();
  }

  #sort_cur_truth_dom() {
    /**
     * 微任务 集
     * @type  {Promise[]}
     */
    let pAll = [];

    /**
     * 当前 按 virtual 排序的 使用的 真实元素
     * @type {string[]}
     */
    let target_truth_dom_oder_Arr = this.#get_cur_truth_dom_oder();

    // 从 最后一个 开始 放置
    let pack_before = (ind) => {
      let cur_node = normalizeContainer(
        get_uni_form_uni_comp_id(target_truth_dom_oder_Arr[ind])
      );

      /**
       * 后一个 元素 或者 static_node 添加栏 按钮元素
       */
      let after_node =
        normalizeContainer(
          get_uni_form_uni_comp_id(target_truth_dom_oder_Arr[ind + 1]),
          true
        ) || normalizeContainer(add_unf_id);

      pAll.push(
        new Promise((resolve) => {
          disappearElFunc(cur_node, undefined, () => {
            // console.log(123);
            packNode(this.targetEl, cur_node, true, after_node);
            appearElFunc(cur_node, undefined, () => {
              resolve();
            });
          });
        })
      );
    };

    let lcs_node = new all_lcs_node(
      target_truth_dom_oder_Arr,
      this.dom_arr_truth
    );

    lcs_node.start();
    /**
     * 第一个 最 长 子序列
     * @type {[]}
     */
    let first_lcs = lcs_node.longest_squence_arr[0];

    for (let ind = target_truth_dom_oder_Arr.length - 1; ind >= 0; ind--) {
      if (first_lcs.includes(target_truth_dom_oder_Arr[ind])) {
        continue;
      }
      pack_before(ind);
    }

    return Promise.all(pAll);
  }

  /**
   * 获取 当前 元素 正确 顺序
   */
  #get_cur_truth_dom_oder() {
    let ret = [];

    this.dom_arr_virtual.forEach((val) => {
      if (this.dom_arr_truth.includes(val)) {
        ret.push(val);
      }
    });

    return ret;
  }

  /**
   * 移除 所有 不需要的 dom
   */
  #remove_all_dom_arr_remove() {
    let pAll = [];
    for (const val of this.dom_arr_remove) {
      pAll.push(
        new Promise((resolve) => {
          element_remove(
            normalizeContainer(get_uni_form_uni_comp_id(val)),
            () => {
              resolve();
            }
          );
        })
      );
    }

    return Promise.all(pAll);
  }

  /**
   * 创建 一个 用于 接受 所有 动态引入 组件 的 隐藏元素
   * 汇总 引入 元素
   */
  #create_all_temp_container_to_dom() {
    // 查询 是否 已存在 全包含组件元素
    this.#all_temp_container_node = document.getElementById(
      all_temp_container_id
    );

    if (this.#all_temp_container_node) {
      return;
    }

    // 如果不存在 则 创建一个
    let a = {
      tag: 'div',
      class: [css_disnone],
      attriKey: ['id'],
      id: all_temp_container_id,
    };

    this.#all_temp_container_node = domTree(a);

    packNode(
      document.body,
      this.#all_temp_container_node,
      true,
      normalizeContainer('app')
    );
  }

  /**
   * 创建 临时 元素 用于 承接 动态引入的 dom
   * 到 汇总 引入 元素
   */
  #create_temp_container_to_all_temp_container(val) {
    let a = {
      tag: 'div',
      attriKey: ['id'],
      id: this.#get_temp_container_id(val),
    };
    let dom = domTree(a);
    packNode(normalizeContainer(all_temp_container_id), dom);
  }

  /**
   * 根据 给定的 val 创建 temp_container 的 id
   * @param {string} val
   * @returns {string}
   */
  #get_temp_container_id(val) {
    return temo_container_id_prefix + val;
  }

  /**
   * 计算 当前 需要移除 的 dom
   */
  #calculate_dom_arr_remove() {
    this.dom_arr_truth.forEach((val) => {
      if (!this.dom_arr_virtual.includes(val)) {
        ObjectOnlyPushSet(this.dom_arr_remove, val);
      }
    });
  }

  /**
   * 计算 当前 需要加载 的 dom
   */
  #calculate_dom_arr_less() {
    this.dom_arr_virtual.forEach((val) => {
      if (!this.dom_arr_truth.includes(val)) {
        ObjectOnlyPushSet(this.dom_arr_less, val);
      }
    });
  }

  #create_temp_container_by_less() {
    this.dom_arr_less.forEach((val) => {
      this.#create_temp_container_to_all_temp_container(val);
    });
  }

  /**
   * 集体 引入 未 加载 的 组件 元素
   */
  #import_less_comps() {
    for (const val of this.dom_arr_less) {
      this.#import_comp(val).then((curkey) => {
        if (this.#start_packnode) {
          this.#pack_node_to_truth_dom(curkey);
        }
      });
    }
  }

  /**
   * 开始 组装 引入 的 元素
   */
  #start_pack_less_comps() {
    // 之后 引入 的 元素 直接 加载到 相应位置
    this.#start_packnode = true;

    // 将 已经 引用的 元素 打包 到 主体
    for (const cur_less_key of this.dom_arr_less) {
      if (this[cur_less_key] != undefined) {
        this.#pack_node_to_truth_dom(cur_less_key);
      }
    }
  }

  /**
   * 引入 和 加载 less 的 元素
   */
  async #import_comp(val) {
    let cur_temp_container_id = this.#get_temp_container_id(val);

    let truth_name_by_val = uni_form_uni_comp_default_cla + '_' + val;

    // console.log(all_uni_comp_module, truth_name_by_val);
    let p = new Promise((resolve) => {
      import(`../../../../${truth_name_by_val}/${truth_name_by_val}.vue`).then(
        (mod) => {
          createApp(mod.default).mount('#' + cur_temp_container_id);

          // 装载 信息
          ObjectOnlyPushSet(
            this,
            val,
            normalizeContainer(cur_temp_container_id).children,
            'dom_arr_load'
          );
          resolve();
        }
      );
    });

    await p;

    return val;
  }

  /**
   * 将 当前 元素 正确 加载 到 指定位置 并 应用 进场动画
   * 同时 dom_arr_truth 增加 该 信息
   * @param {string} compVal
   */
  #pack_node_to_truth_dom(compVal) {
    let comp_node = this[compVal][0];
    // 先 隐藏元素
    add_class(comp_node, css_disnone);

    let {
      isbefore,
      truth_val,
      virtual_val_dom: truth_val_dom,
    } = this.#calculate_cur_compVal_location_dom(compVal);

    // 将元素 放到正确 位置
    packNode(this.targetEl, comp_node, isbefore, truth_val_dom);

    let true_val_ind = this.dom_arr_truth.indexOf(truth_val);

    if (!isbefore) {
      this.dom_arr_truth.splice(true_val_ind, 0, compVal);
    } else {
      this.dom_arr_truth.splice(true_val_ind - 1, 0, compVal);
    }

    // 给元素 添加 进场动画
    element_add(comp_node);
  }

  /**
   * 计算 当前 元素 信息 的 packNode 的 位置
   * @param {string} compVal
   */
  #calculate_cur_compVal_location_dom(compVal) {
    let virtual_val;

    let cur_compVal_ind = this.dom_arr_virtual.indexOf(compVal);

    // 向后 找 真实 dom val
    for (let i = cur_compVal_ind; i < this.dom_arr_virtual.length; i++) {
      virtual_val = this.dom_arr_virtual[i];
      if (this.dom_arr_truth.includes(virtual_val)) {
        return {
          isbefore: true,
          virtual_val,
          virtual_val_dom: normalizeContainer(
            get_uni_form_uni_comp_id(virtual_val)
          ),
        };
      }
    }

    // 向前 找 真实 dom val
    for (let i = cur_compVal_ind; i >= 0; i--) {
      virtual_val = this.dom_arr_virtual[i];
      if (this.dom_arr_truth.includes(virtual_val)) {
        return {
          isbefore: false,
          virtual_val,
          virtual_val_dom: normalizeContainer(
            get_uni_form_uni_comp_id(virtual_val)
          ),
        };
      }
    }

    return {
      isbefore: true,
      virtual_val,
      virtual_val_dom: normalizeContainer(add_unf_id),
    };
  }
}

export { remove_add_anima_factory_dataMana };
